home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / rcs5ap1s.lzh / RCSFCMP.C < prev    next >
C/C++ Source or Header  |  1991-01-30  |  8KB  |  261 lines

  1. /*
  2.  *                     RCS file comparison
  3.  */
  4. /*****************************************************************************
  5.  *                       rcsfcmp()
  6.  *                       Testprogram: define FCMPTEST
  7.  *****************************************************************************
  8.  */
  9.  
  10. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  11.    Copyright 1990 by Paul Eggert
  12.    Distributed under license by the Free Software Foundation, Inc.
  13.  
  14. This file is part of RCS.
  15.  
  16. RCS is free software; you can redistribute it and/or modify
  17. it under the terms of the GNU General Public License as published by
  18. the Free Software Foundation; either version 1, or (at your option)
  19. any later version.
  20.  
  21. RCS is distributed in the hope that it will be useful,
  22. but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24. GNU General Public License for more details.
  25.  
  26. You should have received a copy of the GNU General Public License
  27. along with RCS; see the file COPYING.  If not, write to
  28. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  
  30. Report problems and direct all questions to:
  31.  
  32.     rcs-bugs@cs.purdue.edu
  33.  
  34. */
  35.  
  36.  
  37.  
  38.  
  39.  
  40. /* $Log: rcsfcmp.c,v $
  41.  * Revision 5.6  1991/01/30  14:21:32  apratt
  42.  * CI with RCS version 5
  43.  *
  44.  * Revision 5.5  90/11/27  09:26:05  eggert
  45.  * checked in with -k by apratt at 91.01.10.13.15.12.
  46.  * 
  47.  * Revision 5.5  1990/11/27  09:26:05  eggert
  48.  * Fix comment leader bug.
  49.  *
  50.  * Revision 5.4  1990/11/01  05:03:42  eggert
  51.  * Permit arbitrary data in logs and comment leaders.
  52.  *
  53.  * Revision 5.3  1990/09/11  02:41:15  eggert
  54.  * Don't ignore differences inside keyword strings if -ko is set.
  55.  *
  56.  * Revision 5.1  1990/08/29  07:13:58  eggert
  57.  * Clean old log messages too.
  58.  *
  59.  * Revision 5.0  1990/08/22  08:12:49  eggert
  60.  * Don't append "checked in with -k by " log to logs,
  61.  * so that checking in a program with -k doesn't change it.
  62.  * Ansify and Posixate.  Remove lint.
  63.  *
  64.  * Revision 4.5  89/05/01  15:12:42  narten
  65.  * changed copyright header to reflect current distribution rules
  66.  * 
  67.  * Revision 4.4  88/08/09  19:12:50  eggert
  68.  * Shrink stdio code size.
  69.  * 
  70.  * Revision 4.3  87/12/18  11:40:02  narten
  71.  * lint cleanups (Guy Harris)
  72.  * 
  73.  * Revision 4.2  87/10/18  10:33:06  narten
  74.  * updting version number. Changes relative to 1.1 actually relative to 
  75.  * 4.1
  76.  * 
  77.  * Revision 1.2  87/03/27  14:22:19  jenkins
  78.  * Port to suns
  79.  * 
  80.  * Revision 4.1  83/05/10  16:24:04  wft
  81.  * Marker matching now uses trymatch(). Marker pattern is now
  82.  * checked precisely.
  83.  * 
  84.  * Revision 3.1  82/12/04  13:21:40  wft
  85.  * Initial revision.
  86.  *
  87.  */
  88.  
  89. /*
  90. #define FCMPTEST
  91. */
  92. /* Testprogram; prints out whether two files are identical,
  93.  * except for keywords
  94.  */
  95.  
  96. #include  "rcsbase.h"
  97.  
  98. libId(fcmpId, "$Id: rcsfcmp.c,v 5.6 1991/01/30 14:21:32 apratt Exp $")
  99.  
  100.  
  101.     int
  102. rcsfcmp(xfname,uxfname,delta)
  103.     const char *xfname, *uxfname;
  104.     const struct hshentry *delta;
  105. /* Function: compares the files xfname and uxfname. Returns true
  106.  * if xfname has the same contents as uxfname, while disregarding
  107.  * keyword values. For the LOG-keyword, rcsfcmp skips the log message
  108.  * given by the parameter delta in xfname. Thus, rcsfcmp returns true
  109.  * if xfname contains the same as uxfname, with the keywords expanded.
  110.  * Implementation: character-by-character comparison until $ is found.
  111.  * If a $ is found, read in the marker keywords; if they are real keywords
  112.  * and identical, read in keyword value. If value is terminated properly,
  113.  * disregard it and optionally skip log message; otherwise, compare value.
  114.  */
  115. {
  116.     register int xc,uxc;
  117.     char xkeyword[keylength+2],   uxkeyword[keylength+2];
  118.     int eqkeyvals;
  119.     register FILE * xfp, * uxfp;
  120.     register int delimiter;
  121.     register char * tp;
  122.     register const char *sp;
  123.     int result;
  124.     enum markers match1,match2;
  125.  
  126.     errno = 0;
  127.     if (!(xfp=fopen(sp=xfname,"r")) || !(errno=0, uxfp=fopen(sp=uxfname,"r"))) {
  128.        efaterror(sp);
  129.     }
  130.     result=false;
  131.     delimiter = Expand==OLD_EXPAND ? EOF : KDELIM;
  132.     xc=getc(xfp); uxc=getc(uxfp);
  133.     while( xc == uxc) { /* comparison loop */
  134.         if (xc==EOF) { /* finished; everything is the same*/
  135.             result=true;
  136.             break;
  137.         }
  138.     if (xc != delimiter) {
  139.             /* get the next characters */
  140.             xc=getc(xfp); uxc=getc(uxfp);
  141.         } else {
  142.             /* try to get both keywords */
  143.             tp = xkeyword;
  144.             while( (xc=getc(xfp))!=EOF && (tp< xkeyword+keylength) && (xc!='\n')
  145.                    && (xc!=KDELIM) && (xc!=VDELIM))
  146.                 *tp++ = xc;
  147.         *tp++ = xc;  /* add closing K/VDELIM */
  148.             *tp='\0';
  149.             tp = uxkeyword;
  150.             while( (uxc=getc(uxfp))!=EOF && (tp< uxkeyword+keylength) && (uxc!='\n')
  151.                    && (uxc!=KDELIM) && (uxc!=VDELIM))
  152.                 *tp++ = uxc;
  153.         *tp++ = xc;  /* add closing K/VDELIM */
  154.             *tp='\0';
  155.         /* Now we have 2 keywords, or something that looks like it. */
  156.         match1 = trymatch(xkeyword);
  157.         match2 = trymatch(uxkeyword);
  158.         if (match1 != match2) break; /* not identical */
  159. #ifdef FCMPTEST
  160.         VOID printf("found potential keywords %s and %s\n",xkeyword,uxkeyword);
  161. #endif
  162.  
  163.         if (match1 == Nomatch) {
  164.         /* not a keyword pattern, but could still be identical */
  165.         if (strcmp(xkeyword,uxkeyword)==0)
  166.              continue;
  167.         else break;
  168.         }
  169. #ifdef FCMPTEST
  170.         VOID printf("found common keyword %s\n",xkeyword);
  171. #endif
  172.         eqkeyvals = 1;
  173.         for (;;) {
  174.         if (xc==uxc) {
  175.             if (xc==KDELIM)
  176.             break;
  177.         } else {
  178.             eqkeyvals = 0;
  179.             if (xc==KDELIM) {
  180.             while (uxc!=KDELIM && uxc!='\n' && uxc!=EOF)
  181.                 uxc = getc(uxfp);
  182.             break;
  183.             }
  184.             if (uxc==KDELIM) {
  185.             while (xc!=KDELIM && xc!='\n' && xc!=EOF)
  186.                 xc = getc(xfp);
  187.             break;
  188.             }
  189.         }
  190.         if (xc=='\n' || uxc=='\n' || xc==EOF || uxc==EOF)
  191.             break;
  192.         xc = getc(xfp);
  193.         uxc = getc(uxfp);
  194.         }
  195.         if (xc!=uxc) break; /* not the same */
  196.         if (xc==KDELIM) {
  197.         xc=getc(xfp); uxc=getc(uxfp); /* skip closing KDELIM */
  198.         /* if the keyword is LOG, also skip the log message in xfp*/
  199.         if (match1==Log) {
  200.             /* first, compute the number of line feeds in log msg */
  201.             unsigned lncnt;
  202.             size_t ls, ccnt;
  203.             lncnt = 3;
  204.             sp = delta->log.string;
  205.             ls = delta->log.size;
  206.             if (sizeof(ciklog)-1<=ls && !strncmp(sp,ciklog,sizeof(ciklog)-1))
  207.             continue; /* this log message wasn't inserted */
  208.             while (ls--) if (*sp++=='\n') lncnt++;
  209.             while(xc!=EOF) {
  210.             if (xc=='\n')
  211.                 if(--lncnt==0) break;
  212.             xc=getc(xfp);
  213.             }
  214.             /* skip last comment leader */
  215.             /* Can't just skip another line here, because there may be */
  216.             /* additional characters on the line (after the Log....$)  */
  217.             for (ccnt=Comment.size; ccnt--; ) {
  218.             xc=getc(xfp);
  219.             if(xc=='\n') break;
  220.             /* reads to the end of the comment leader or '\n',     */
  221.             /* whatever comes first. This is because some editors  */
  222.             /* strip off trailing blanks from a leader like " * ". */
  223.             }
  224.         }
  225.         } else {
  226.         /* both end in the same character, but not a KDELIM */
  227.         /* must compare string values.*/
  228. #ifdef FCMPTEST
  229.         VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword);
  230. #endif
  231.         if (!eqkeyvals) break;
  232.             }
  233.         }
  234.     }
  235.     ffclose(xfp); ffclose(uxfp);
  236.     return result;
  237. }
  238.  
  239.  
  240.  
  241. #ifdef FCMPTEST
  242.  
  243. const char cmdid[] = "rcsfcmp";
  244.  
  245. main(argc, argv)
  246. int  argc; char  *argv[];
  247. /* first argument: comment leader; 2nd: log message, 3rd: expanded file,
  248.  * 4th: unexpanded file
  249.  */
  250. {       struct hshentry delta;
  251.  
  252.     Comment.string = argv[1];
  253.     Comment.size = strlen(argv[1]);
  254.     delta.log.string = argv[2];
  255.     delta.log.size = strlen(argv[2]);
  256.         if (rcsfcmp(argv[3],argv[4],&delta))
  257.                 VOID printf("files are the same\n");
  258.         else    VOID printf("files are different\n");
  259. }
  260. #endif
  261.